//
//  CNM_Keychain.swift
//  swiftTXH
//
//  Created by Mac mini on 2021/1/14.
//  Copyright © 2021 Mac mini. All rights reserved.
//

import UIKit
import Security
import CoreFoundation

public struct CNM_Keychain {
    ///单例
    public static let `default` = CNM_Keychain()
    private init() {}
}

public extension CNM_Keychain {
    /// 存储
    func save(service: String, data: Any?) {
        guard let _data = data else {
            assertionFailure("请传入需要保存的数据")
            return
        }
        
        var keychainQuery = getKeychainQuery(service: service)
        // 删除之前service对应的就数据
        SecItemDelete(keychainQuery as CFDictionary)
        // 更新/添加keychain
        keychainQuery.updateValue(NSKeyedArchiver.archivedData(withRootObject: _data), forKey: kSecValueData as String)
        SecItemAdd(keychainQuery as CFDictionary, nil)
    }
    
    // 读取
    func load(service: String) -> Data? {
        var keychainQuery = getKeychainQuery(service: service)
        
        // 添加查询条件
        keychainQuery.updateValue(kSecMatchLimitOne, forKey: kSecMatchLimit as String)
        keychainQuery.updateValue(kCFBooleanTrue!, forKey: kSecReturnData as String)
        
        // 开始查询
        var dataTypeRef: AnyObject?
        let status = withUnsafePointer(to: &dataTypeRef) {SecItemCopyMatching(keychainQuery as CFDictionary, UnsafeMutablePointer(mutating: $0))}
        
        
        if status == errSecSuccess {
            if let data = dataTypeRef as? Data {
                return data
            }
        }
        return nil
    }
    
    // 删除
    @discardableResult
    func delete(service: String) -> Bool {
        let keychainQuery = getKeychainQuery(service: service)
        let status = SecItemDelete(keychainQuery as CFDictionary)
        return status == noErr
    }
}

/* 知识点：
 条目类别kSecClass，条目类别是一个条目最基本的属性，每个存入keychain的条目，都需要为它定义一个类别，实际就是你用该条目存储什么样的数据。
 key: kSecAttrAccessible：可访问的；
 value: kSecAttrAccessibleWhenUnlocked 默认在设备未锁屏的情况下
        kSecAttrAccessibleAfterFirstUnlock 在设备第一次解锁后，可以使用
 */
extension CNM_Keychain {
    /// 查询条件操作
    private func getKeychainQuery(service: String) -> [String: Any] {
        let kClassKey = kSecClass as String
        let kAccessibleKey = kSecAttrAccessible as String // Accessible: 可访问的
        let kServiceKey = kSecAttrService as String
        let kAccountKey = kSecAttrAccount as String
        
        let dict: [String : Any] = [
            kClassKey: kSecClassGenericPassword, // 需要存储的类别
            kServiceKey: service, // 条目所属服务
            kAccountKey: service, // 条目所属账户名
            kAccessibleKey: kSecAttrAccessibleAfterFirstUnlock
        ]
        
        return dict
    }
}


public struct CNM_UserDefaults {
    // 存储
    public static func setValue(value: Any?, forKey: String) {
        cnm_ud.setValue(value, forKey: forKey)
    }
    
    // 获取
    public static func getValue(forKey key: String) {
        cnm_ud.value(forKey: key)
    }
}

